package com.yycx.base.provider.listener;

import com.yycx.common.base.entity.EntityMap;
import com.yycx.common.constants.CommonConstants;
import com.yycx.common.constants.QueueConstants;
import com.yycx.common.security.http.OpenRestTemplate;
import com.yycx.common.base.utils.FlymeUtils;
import com.yycx.common.utils.JsonUtils;
import com.yycx.common.utils.RedisUtils;
import com.yycx.module.admin.client.entity.BaseAction;
import com.yycx.module.admin.client.entity.BaseApi;
import com.yycx.module.admin.client.entity.BaseMenu;
import com.yycx.module.admin.provider.service.BaseActionService;
import com.yycx.module.admin.provider.service.BaseApiService;
import com.yycx.module.admin.provider.service.BaseAuthorityService;
import com.yycx.module.admin.provider.service.BaseMenuService;
import com.yycx.starter.rabbitmq.config.RabbitComponent;
import com.yycx.starter.rabbitmq.core.BaseRabbiMqHandler;
import com.yycx.starter.rabbitmq.listener.MqListener;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.handler.annotation.Header;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * mq消息接收者
 *
 * @author zyf
 */
@Configuration
@Slf4j
@RabbitComponent(value = "resourceScanHandler")
public class ResourceScanHandler extends BaseRabbiMqHandler<EntityMap> {
    @Autowired
    private BaseApiService baseApiService;
    @Autowired
    private BaseAuthorityService baseAuthorityService;
    @Autowired
    private OpenRestTemplate restTemplate;


    @Autowired
    private BaseActionService baseActionService;

    @Autowired
    private BaseMenuService baseMenuService;

    @Autowired
    private RedisUtils redisUtils;


    /**
     * 监听API资源扫描
     */
    @RabbitListener(queues = QueueConstants.QUEUE_SCAN_API_RESOURCE)
    public void scanApiResourceQueue(EntityMap entityMap, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag) {
        super.onMessage(entityMap, deliveryTag, channel, new MqListener<EntityMap>() {
            @Override
            public void handler(EntityMap entityMap, Channel channel) {
                try {
                    log.info("**********************************监听API资源扫描*************************************");
                    String serviceId = entityMap.get("application");
                    List array = entityMap.get("mapping");
                    if (FlymeUtils.isNotEmpty(array)) {
                        List codesArray = entityMap.get("codes");
                        Iterator iterator = array.iterator();
                        while (iterator.hasNext()) {
                            Map map = (Map) iterator.next();
                            try {
                                BaseApi api = JsonUtils.jsonToBean(JsonUtils.beanToJson(map), BaseApi.class);
                                BaseApi baseApi = baseApiService.getApi(api.getApiCode());
                                String actionName = api.getActionName();
                                String menuName = api.getMenuName();
                                //当菜名名称不为空时创建按钮
                                if (FlymeUtils.isNotEmpty(menuName)) {
                                    String actionCode = api.getMethodName();
                                    Boolean insert = false;
                                    BaseAction baseAction = baseActionService.getAction(actionCode);
                                    if (FlymeUtils.isEmpty(baseAction)) {
                                        baseAction = new BaseAction();
                                        insert = true;
                                    }
                                    baseAction.setIsPersist(CommonConstants.LEVEL_1);
                                    baseAction.setStatus(CommonConstants.ENABLED);
                                    baseAction.setActionCode(actionCode);
                                    baseAction.setActionName(actionName);
                                    baseAction.setServiceId(api.getServiceId());
                                    BaseMenu baseMenu = baseMenuService.getMenu(menuName);
                                    if (FlymeUtils.isNotEmpty(baseMenu)) {
                                        baseAction.setMenuId(baseMenu.getMenuId());
                                    }
                                    if (insert) {
                                        baseActionService.addAction(baseAction);
                                    } else {
                                        baseActionService.updateAction(baseAction);
                                    }
                                }
                                if (FlymeUtils.isEmpty(baseApi)) {
                                    api.setIsOpen(1);
                                    api.setIsPersist(1);
                                    baseApiService.addApi(api);
                                } else {
                                    api.setApiId(baseApi.getApiId());
                                    //更新时忽略权限字段
                                    api.setIsAuth(null);
                                    baseApiService.updateApi(api);
                                }

                            } catch (Exception e) {
                                e.printStackTrace();
                                log.error("添加资源error:", e.getMessage());
                            }

                        }
                        if (FlymeUtils.isNotEmpty(codesArray)) {
                            List<String> codes = codesArray;
                            // 清理无效权限数据
                            baseAuthorityService.clearInvalidApi(serviceId, codes);
                            restTemplate.refreshGateway();
                        }
                    }

                } catch (Exception e) {
                    log.error("error:", e);
                }

            }
        });
    }
}
